﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.ServiceModel;
using System.Threading.Tasks;
using System.Threading;

using YLClient;
using YLClient.Config;
using YLClient.YLServiceClient;

namespace YLClient
{

    /// <summary>
    /// Interaction logic for Login.xaml
    /// </summary>
    public partial class Login : Window
    {
        /// <summary>
        /// UI控制
        /// </summary>
        public void Ready()
        {
            pgbLogin.Visibility = Visibility.Hidden;
            btnLogin.IsEnabled = true;
            btnNetworkSet.IsEnabled = true;
            txtName.IsEnabled = true;
            txtPwd.IsEnabled = true;
        }
        /// <summary>
        /// UI控制
        /// </summary>
        public void Work()
        {
            pgbLogin.Visibility = Visibility.Visible;
            btnLogin.IsEnabled = false;
            btnNetworkSet.IsEnabled = false;
            txtName.IsEnabled = false;
            txtPwd.IsEnabled = false;
        }


        /// <summary>
        /// GUI线程的
        /// </summary>
        private TaskScheduler guiSyncTaskScheduler;
        /// <summary>
        /// 取消任务的TokenSource
        /// </summary>
        private CancellationTokenSource loginCancelTokenSource;

        private CancellationTokenSource afterLoginCancelTokenSource;

        /// <summary>
        /// 初始化UI工作
        /// </summary>
        private void initialUi()
        {
            txtName.Text = ClientConfig.AutoLoginName;
            txtPwd.Password = ClientConfig.AutoLoginPwd;
        }

        /// <summary>
        /// 初始化数据
        /// </summary>
        private void initialData()
        {
            loginCancelTokenSource = new CancellationTokenSource();
            afterLoginCancelTokenSource = new CancellationTokenSource();
            guiSyncTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        }
        /// <summary>
        /// 构造函数
        /// </summary>
        public Login()
        {
            InitializeComponent();
            initialUi();
            initialData();
        }

        private Guid login(string name, string pwd)
        {
            var client = ServiceClient.GetServiceClient();
            if (client.State != CommunicationState.Opened)
            {
                client.Open();
            }
            var guid = client.Login(name, pwd);
            if (guid == Guid.Empty)
            {
                throw new Exception("帐户或者密码出错");
            }
            return guid;
        }


        private Tuple<string, string> beforeLogin()
        {
            Work();
            return Tuple.Create(txtName.Text, txtPwd.Password);
        }
        /// <summary>
        /// 登录成功后被执行
        /// </summary>
        /// <param name="loginTask"></param>
        private void afterLogin(Task<Guid> loginTask)
        {
            if (loginTask.Result != Guid.Empty)
            {
                #region 保存当前登录帐号
                ClientConfig.AutoLoginName = txtName.Text;
                ClientConfig.AutoLoginPwd = txtPwd.Password;
                ClientConfig.Save(); 
                #endregion
                MainWindow main = new MainWindow();
                main.Show();
                main.Closed += new EventHandler((o, arg) =>
                    this.Close());
                this.Hide();
            }
            else
            {
                MessageBox.Show("帐号或密码错误！", "提示", MessageBoxButton.OK);
                Ready();
            }
        }
        /// <summary>
        /// 登录过程发生异常时
        /// </summary>
        /// <param name="loginTask"></param>
        private void faultedLogin(Task<Guid> loginTask)
        {
            MessageBox.Show("登录过程:" + loginTask.Exception.Message, "提示", MessageBoxButton.OK);
            Ready();
        }

        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            var beforeLoginTask = Task.Factory.StartNew<Tuple<string, string>>(
                beforeLogin,
                new CancellationToken(),
                TaskCreationOptions.None,
                guiSyncTaskScheduler);

            var loginTask = beforeLoginTask.ContinueWith(
                 task => login(task.Result.Item1, task.Result.Item2),
                 loginCancelTokenSource.Token
                 );

            //正常登录交互后执行
            loginTask.ContinueWith(
                task => afterLogin(task),
                 afterLoginCancelTokenSource.Token,
                TaskContinuationOptions.NotOnCanceled | TaskContinuationOptions.NotOnFaulted,
                guiSyncTaskScheduler);//传入UI的是调度器就是在UI线程上执行
            //登录交互异常时执行
            loginTask.ContinueWith(
                task => faultedLogin(task),
                 afterLoginCancelTokenSource.Token,
                TaskContinuationOptions.OnlyOnFaulted,
                guiSyncTaskScheduler);//传入UI的是调度器就是在UI线程上执行

        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            txtName.Focus();
        }
    }
}
